home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Tools 3
/
Amiga Tools 3.iso
/
grafik
/
raytracing
/
magiccamera
/
misc
/
t2a2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-18
|
23KB
|
873 lines
/***********************************************************
*
* This file is Copyright © 1990-1994 Dan Wesnor
*
* This file and any executables resulting from compilation
* of this file are freely distributable so long as the
* above copyright statement is included intact. This
* statement of distributability is limited to this file
* only, and does not include any other file in this
* archive.
*
* No gaurantees of usability are made for this file or
* any executables generated from it. Use at your own risk.
*
************************************************************
*
* This program generates an MC script from a 3DDD object
* file as generated by Impulse's renderers (Turbo Silver
* and Imagine). This version show how to generate objects
* using vertex based definitions of triangles.
*
* The 3DDD parser is not all that great, and could be
* improved upon. Someone could also use this code as
* a basis for a program which generates scripts from other
* object formats as well.
*
* NOTE: be careful using this code on machines with
* int lengths other than 32 bits!
*
***********************************************************/
#include "turbo.h"
#include <fcntl.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#ifndef max
#define max(a,b) (((a)>(b))?(a):(b))
#endif
#ifndef min
#define min(a,b) (((a)<(b))?(a):(b))
#endif
typedef struct {
unsigned int form,
size,
type;
} Form, *FormPtr;
#define MakeName(s) (((s)[0]<<24)+((s)[1]<<16)+((s)[2]<<8)+(s)[3])
typedef struct {
unsigned int name,
len;
} Chunk, *ChunkPtr;
#define ReadData(f,b,s) read((f),(b),(s)+((s)%2)) /* force a read of even bytes */
typedef struct str_surface {
struct str_surface *next;
int num;
COLOR colr,
refl,
tran;
UBYTE hard,
spec,
index;
char name[32];
} Surface, *SurfacePtr;
#define QUIET 0x0
#define TERSE 0x1
#define VERBOSE 0x2
#define FND_PNTS 0x1
#define FND_POSI 0x2
#define FND_NAME 0x4
#define FND_SHAP 0x8
#define FND_AXIS 0x10
#define FND_SIZE 0x20
#define FND_EDGE 0x40
#define FND_FACE 0x80
#define FND_COLR 0x100
#define FND_REFL 0x200
#define FND_TRAN 0x400
#define FND_CLST 0x800
#define FND_SPEC 0x1000
#define FND_TLST 0x2000
#define FND_RLST 0x4000
#define FND_MTTR 0x8000
#define FND_INTS 0x10000
#define FND_PRP0 0x20000
#define FND_SPC1 0x40000
#define FND_PRP1 0x80000
FILE *ofh=0;
char *filename;
unsigned char printmode = TERSE;
long flags=0;
#define FL_OBJECTS 0x1
#define CHECKTERSE if (printmode >= TERSE)
#define CHECKVERBOSE if (printmode >= VERBOSE)
float scalefactor=1.0;
SurfacePtr surfList=NULL;
SurfacePtr MakeSurface(UBYTE cr, UBYTE cg, UBYTE cb, UBYTE rr, UBYTE rg, UBYTE rb, UBYTE tr, UBYTE tg, UBYTE tb, UBYTE h, UBYTE s, UBYTE i)
{
SurfacePtr surf;
surf = surfList;
while (surf)
{
if ((surf->colr[0] == cr) && (surf->colr[1] == cg) && (surf->colr[2] == cb)
&& (surf->refl[0] == rr) && (surf->refl[1] == rg)
&& (surf->refl[2] == rb)
&& (surf->tran[0] == tr) && (surf->tran[1] == tg)
&& (surf->tran[2] == tb)
&& (surf->hard == h) && (surf->spec == s)
&& (surf->index == i))
return surf;
surf = surf->next;
}
if (!(surf = (SurfacePtr)calloc(1, sizeof(Surface))))
{
fprintf(stdout, "Cannot allocate new color\n");
return surfList;
}
surf->num = surfList ? surfList->num+1 : 0;
surf->next = surfList;
surfList = surf;
surf->colr[0] = cr;
surf->colr[1] = cg;
surf->colr[2] = cb;
surf->refl[0] = rr;
surf->refl[1] = rg;
surf->refl[2] = rb;
surf->tran[0] = tr;
surf->tran[1] = tg;
surf->tran[2] = tb;
surf->hard = h;
surf->spec = s;
surf->index = i;
sprintf(surf->name, "T2AS_%s_%d", filename, surf->num);
fprintf(ofh, "color %s {\n", surf->name);
fprintf(ofh, "\tdiff\t<%f, %f, %f>\n", cr/255.0, cg/255.0, cb/255.0);
if (tr && tg && tb)
fprintf(ofh, "\ttrans\t<%f, %f, %f>\n", tr/255.0, tg/255.0, tb/255.0);
if (rr && rg && rb)
fprintf(ofh, "\trefl\t<%f, %f, %f>\n", rr/255.0, rg/255.0, rb/255.0);
if (s)
{
fprintf(ofh, "\tpcoef\t%f\n", h/5.0);
fprintf(ofh, "\tprefl\t%f\n", s/255.0);
}
if (i)
fprintf(ofh, "\tindex\t%f\n", i/100.0+1.0);
fprintf(ofh, "}\n\n");
return surf;
}
float imn[3]={1e6, 1e6, 1e6}, imx[3]={-1e6, -1e6, -1e6};
void GetDescChunk(int ifd, int len)
{
Chunk chunk;
int whatami=0;
int found=0;
int i, p1, p2, p3;
int degen;
SurfacePtr surf;
PNTS *pnts;
POSI posi;
NAME name;
SHAP shap;
AXIS axis;
SIZE size;
EDGE *edge;
FACE *face;
COLR colr;
REFL refl;
TRAN tran;
SPC1 spc1;
CLST *clst;
SPEC spec;
TLST *tlst;
RLST *rlst;
MTTR mttr;
INTS ints;
PRP0 prp;
PRP1 prp1;
colr.col[0] = colr.col[1] = colr.col[2] = 255;
refl.col[0] = refl.col[1] = refl.col[2] = 0;
tran.col[0] = tran.col[1] = tran.col[2] = 0;
while (len)
{
len -= read(ifd, &chunk, sizeof(Chunk));
chunk.len += chunk.len % 2;
if (chunk.name == MakeName("NAME"))
{
len -= ReadData(ifd, &name, sizeof(NAME));
CHECKVERBOSE { fprintf(stdout, "\t\tNAME: %s\n", name.Name); }
}
else if (chunk.name == MakeName("SHAP"))
{
len -= ReadData(ifd, &shap, sizeof(SHAP));
CHECKVERBOSE { fprintf(stdout, "\t\tSHAP: "); }
switch (shap.Lamp)
{
case LMP_NOTALAMP:
whatami = shap.Shape;
switch (shap.Shape)
{
case SHP_SPHERE:
CHECKVERBOSE { fprintf(stdout, "sphere\n"); }
break;
case SHP_STENCIL:
CHECKVERBOSE { fprintf(stdout, "stencil\n"); }
break;
case SHP_AXIS:
CHECKVERBOSE { fprintf(stdout, "axis\n"); }
break;
case SHP_FACETS:
CHECKVERBOSE { fprintf(stdout, "facets\n"); }
break;
case SHP_SURFACE:
CHECKVERBOSE { fprintf(stdout, "Surface\n"); }
break;
case SHP_GROUND:
CHECKVERBOSE { fprintf(stdout, "Ground\n"); }
break;
default:
CHECKTERSE { fprintf(stdout, "Unknown: %d\n",
shap.Shape); }
break;
}
break;
case LMP_SUN:
CHECKVERBOSE { fprintf(stdout, "Lamp (Sun)\n"); }
break;
case LMP_LAMP:
CHECKVERBOSE { fprintf(stdout, "Lamp (Lamp)\n"); }
break;
default:
break;
}
}
else if (chunk.name == MakeName("POSI"))
{
found |= FND_POSI;
len -= ReadData(ifd, &posi, sizeof(POSI));
CHECKVERBOSE { fprintf(stdout, "\t\tPOSI: <%f, %f, %f>\n",
posi.Position.X/65536.0,
posi.Position.Y/65536.0, posi.Position.Z/65536.0); }
}
else if (chunk.name == MakeName("AXIS"))
{
found |= FND_AXIS;
len -= ReadData(ifd, &axis, sizeof(AXIS));
CHECKVERBOSE { fprintf(stdout, "\t\tAXIS: X = <%f, %f, %f>\n",
axis.XAxis.X/65536.0, axis.XAxis.Z/65536.0,
axis.XAxis.Y/65536.0); }
CHECKVERBOSE { fprintf(stdout, "\t\t Y = <%f, %f, %f>\n",
axis.YAxis.X/65536.0, axis.YAxis.Z/65536.0,
axis.YAxis.Y/65536.0); }
CHECKVERBOSE { fprintf(stdout, "\t\t Z = <%f, %f, %f>\n",
axis.ZAxis.X/65536.0, axis.ZAxis.Z/65536.0,
axis.ZAxis.Y/65536.0); }
}
else if (chunk.name == MakeName("SIZE"))
{
found |= FND_SIZE;
len -= ReadData(ifd, &size, sizeof(SIZE));
CHECKVERBOSE { fprintf(stdout, "\t\tSIZE: <%f, %f, %f>\n",
size.Size.X/65536.0, size.Size.Y/65536.0,
size.Size.Z/65536.0); }
}
else if (chunk.name == MakeName("PNTS"))
{
if (pnts = (PNTS *)calloc(1, chunk.len))
{
found |= FND_PNTS;
len -= ReadData(ifd, &(pnts->PCount), 2);
len -= ReadData(ifd, pnts->Points, chunk.len-2);
CHECKVERBOSE { fprintf(stdout, "\t\tPNTS: %d\n", pnts->PCount); }
fprintf(ofh, "flushverts\n\n");
for (i=0; i<pnts->PCount; i++)
fprintf(ofh, "vertex T2AV_%d <%f, %f, %f>\n", i, -scalefactor*pnts->Points[i].X/65536.0,
scalefactor*pnts->Points[i].Z/65536.0, scalefactor*pnts->Points[i].Y/65536.0);
fprintf(ofh, "\n");
}
else
fprintf(stdout, "PNTS found, no memory to load\n");
}
else if (chunk.name == MakeName("EDGE"))
{
if (edge = (EDGE *)calloc(1, chunk.len))
{
found |= FND_EDGE;
len -= ReadData(ifd, edge, chunk.len);
CHECKVERBOSE { fprintf(stdout, "\t\tEDGE: %d\n", edge->ECount); }
}
else
fprintf(stdout, "EDGE found, no memory to load\n");
}
else if (chunk.name == MakeName("FACE"))
{
if (face = (FACE *)calloc(1, chunk.len))
{
found |= FND_FACE;
len -= ReadData(ifd, face, chunk.len);
CHECKVERBOSE { fprintf(stdout, "\t\tFACE: %d\n", face->TCount); }
}
else
fprintf(stdout, "FACE found, no memory to load\n");
}
else if (chunk.name == MakeName("COLR"))
{
found |= FND_COLR;
len -= ReadData(ifd, &colr, sizeof(COLR));
CHECKVERBOSE { fprintf(stdout, "\t\tCOLR: %d %d %d\n",
colr.col[0], colr.col[1], colr.col[2]); }
}
else if (chunk.name == MakeName("REFL"))
{
found |= FND_REFL;
len -= ReadData(ifd, &refl, sizeof(REFL));
CHECKVERBOSE { fprintf(stdout, "\t\tREFL: %d %d %d\n",
refl.col[0], refl.col[1], refl.col[2]); }
}
else if (chunk.name == MakeName("TRAN"))
{
found |= FND_TRAN;
len -= ReadData(ifd, &tran, sizeof(TRAN));
CHECKVERBOSE { fprintf(stdout, "\t\tTRAN: %d %d %d\n",
tran.col[0], tran.col[1], tran.col[2]); }
}
else if (chunk.name == MakeName("SPC1"))
{
found |= FND_SPC1;
len -= ReadData(ifd, &tran, sizeof(TRAN));
CHECKVERBOSE fprintf(stdout, "\t\tSPC1: %d %d %d\n",
spc1.col[0], spc1.col[1], spc1.col[2]);
}
else if (chunk.name == MakeName("CLST"))
{
if (clst = (CLST *)calloc(1, chunk.len))
{
found |= FND_CLST;
len -= ReadData(ifd, clst, chunk.len);
CHECKVERBOSE { fprintf(stdout, "\t\tCLST: %d\n", clst->count); }
}
else
fprintf(stdout, "CLST found, no memory to load\n");
}
else if (chunk.name == MakeName("RLST"))
{
if (rlst = (RLST *)calloc(1, chunk.len))
{
found |= FND_RLST;
len -= ReadData(ifd, rlst, chunk.len);
CHECKVERBOSE { fprintf(stdout, "\t\tRLST: %d\n", rlst->count); }
}
else
fprintf(stdout, "RLST found, no memory to load\n");
}
else if (chunk.name == MakeName("TLST"))
{
if (tlst = (TLST *)calloc(1, chunk.len))
{
found |= FND_TLST;
len -= ReadData(ifd, tlst, chunk.len);
CHECKVERBOSE { fprintf(stdout, "\t\tTLST: %d\n", tlst->count); }
}
else
fprintf(stdout, "TLST found, no memory to load\n");
}
else if (chunk.name == MakeName("TPAR"))
{
CHECKVERBOSE { fprintf(stdout, "\t\tTPAR: found\n"); }
lseek(ifd, chunk.len, 1);
len -= chunk.len;
}
else if (chunk.name == MakeName("SURF"))
{
fprintf(stdout, "\t\tSURF: found\n");
lseek(ifd, chunk.len, 1);
len -= chunk.len;
}
else if (chunk.name == MakeName("MTTR"))
{
found |= FND_MTTR;
len -= ReadData(ifd, &mttr, sizeof(MTTR));
switch (mttr.Type)
{
case RFR_AIR:
CHECKVERBOSE { fprintf(stdout, "\t\tMTTR: %f (Air)\n", VAL_AIR); }
break;
case RFR_WATER:
CHECKVERBOSE { fprintf(stdout, "\t\tMTTR: %f (Water)\n",
VAL_WATER); }
break;
case RFR_GLASS:
CHECKVERBOSE { fprintf(stdout, "\t\tMTTR: %f (Glass)\n",
VAL_GLASS); }
break;
case RFR_CRYSTAL:
CHECKVERBOSE { fprintf(stdout, "\t\tMTTR: %f (Crystal)\n",
VAL_CRYSTAL); }
break;
case RFR_CUSTOM:
CHECKVERBOSE { fprintf(stdout, "\t\tMTTR: %f (Custom)\n",
VAL_CUSTOM(mttr.Index)); }
break;
default:
CHECKTERSE { fprintf(stdout, "\t\tMTTR: unknown type %d\n",
mttr.Type); }
break;
}
}
else if (chunk.name == MakeName("SPEC"))
{
found |= FND_SPEC;
len -= ReadData(ifd, &spec, sizeof(SPEC));
fprintf(stdout, "\t\tSPEC: Spec=%d, Hard=%d\n",
spec.Specularity, spec.Hardness);
}
else if (chunk.name == MakeName("PRP0"))
{
found |= FND_PRP0;
len -= ReadData(ifd, &prp, sizeof(PRP0));
CHECKVERBOSE { fprintf(stdout, "\t\tPRP0: Blend = %d\n", prp.Props[PRP_BLEND]); }
CHECKVERBOSE { fprintf(stdout, "\t\t Rough = %d\n", prp.Props[PRP_SMOOTH]); }
CHECKVERBOSE { fprintf(stdout, "\t\t Shade = %s\n",
prp.Props[PRP_SHADE] ? "ON" : "OFF"); }
CHECKVERBOSE { fprintf(stdout, "\t\t Phong = %s\n",
prp.Props[PRP_PHONG] ? "OFF" : "ON"); }
CHECKVERBOSE { fprintf(stdout, "\t\t Glossy = %s\n",
prp.Props[PRP_GLOSSY] ? "ON" : "OFF"); }
CHECKVERBOSE { fprintf(stdout, "\t\t Quick = %s\n",
prp.Props[PRP_QUICK] ? "ON" : "OFF"); }
}
else if (chunk.name = MakeName("PRP1"))
{
found |= FND_PRP1;
len -= ReadData(ifd, &prp1, sizeof(PRP1));
CHECKVERBOSE fprintf(stdout, "\t\tPRP1: Blend = %d\n", prp1.Props[PRP1_DITHER]);
CHECKVERBOSE fprintf(stdout, "\t\t Hardness = %d\n", prp1.Props[PRP1_HARD]);
CHECKVERBOSE fprintf(stdout, "\t\t Roughness = %d\n", prp1.Props[PRP1_ROUGH]);
CHECKVERBOSE fprintf(stdout, "\t\t Shine = %d\n", prp1.Props[PRP1_SHINY]);
CHECKVERBOSE fprintf(stdout, "\t\t Index = %d\n", prp1.Props[PRP1_INDEX]);
CHECKVERBOSE fprintf(stdout, "\t\t Quick Draw = %s\n", (prp1.Props[PRP1_QUICK])?"ON":"OFF");
CHECKVERBOSE fprintf(stdout, "\t\t Phong = %s\n", (prp1.Props[PRP1_PHONG])?"ON":"OFF");
CHECKVERBOSE fprintf(stdout, "\t\t Genlock = %s\n", (prp1.Props[PRP1_GENLOCK])?"ON":"OFF");
}
else if (chunk.name == MakeName("INTS"))
{
found |= FND_INTS;
len -= ReadData(ifd, &ints, sizeof(INTS));
CHECKVERBOSE { fprintf(stdout, "\t\tINTS: %f\n", ints.Intensity/65536.0); }
}
else if (chunk.name == MakeName("STRY"))
{
CHECKVERBOSE { fprintf(stdout, "\t\tSTRY: found\n"); }
lseek(ifd, chunk.len, 1);
len -= chunk.len;
}
else
{
CHECKTERSE { fprintf(stdout, "\t\t%.4s: Found unknown chunk, skipping\n", &chunk.name); }
lseek(ifd, chunk.len, 1);
len -= chunk.len;
}
}
if (whatami == SHP_AXIS)
{
float mx[3]={-1e6, -1e6, -1e6}, mn[3]={1e6, 1e6, 1e6};
degen = 0;
if (pnts && edge && face)
CHECKTERSE { fprintf(stdout, "Dumping axis type object named \"%s\" with %d points, %d edges, and %d faces.\n",
name.Name, pnts->PCount, edge->ECount, face->TCount); }
fprintf(ofh, "/* --------- %s --------- */\n", name.Name);
if (((found & FND_PRP0) && (!(prp.Props[PRP_SMOOTH]))) || ((found & FND_PRP1) && (!(prp1.Props[PRP1_PHONG]))))
fprintf(ofh, "smoothon\n");
if ((found & (FND_PNTS | FND_EDGE | FND_FACE))
!= (FND_PNTS | FND_EDGE | FND_FACE))
{ CHECKTERSE fprintf(stdout, "***\tError: One of PNTS, EDGE, or FACE not found or allocated\n"); }
else
{
for (i=0; i<pnts->PCount; i++)
{
pnts->Points[i].X *= -1.0;
mx[0] = max(mx[0], pnts->Points[i].X/65536.0);
mn[0] = min(mn[0], pnts->Points[i].X/65536.0);
imx[0] = max(imx[0], pnts->Points[i].X/65536.0);
imn[0] = min(imn[0], pnts->Points[i].X/65536.0);
mx[1] = max(mx[1], pnts->Points[i].Y/65536.0);
mn[1] = min(mn[1], pnts->Points[i].Y/65536.0);
imx[1] = max(imx[1], pnts->Points[i].Y/65536.0);
imn[1] = min(imn[1], pnts->Points[i].Y/65536.0);
mx[2] = max(mx[2], pnts->Points[i].Z/65536.0);
mn[2] = min(mn[2], pnts->Points[i].Z/65536.0);
imx[2] = max(imx[2], pnts->Points[i].Z/65536.0);
imn[2] = min(imn[2], pnts->Points[i].Z/65536.0);
}
for (i=0; i<face->TCount; i++)
{
surf = MakeSurface(
(found & FND_CLST)? clst->colors[i][0]: colr.col[0],
(found & FND_CLST)? clst->colors[i][1]: colr.col[1],
(found & FND_CLST)? clst->colors[i][2]: colr.col[2],
(found & FND_RLST)? rlst->colors[i][0]: refl.col[0],
(found & FND_RLST)? rlst->colors[i][1]: refl.col[1],
(found & FND_RLST)? rlst->colors[i][2]: refl.col[2],
(found & FND_TLST)? tlst->colors[i][0]: tran.col[0],
(found & FND_TLST)? tlst->colors[i][1]: tran.col[1],
(found & FND_TLST)? tlst->colors[i][2]: tran.col[2],
(found & FND_SPEC) ? spec.Hardness : 0,
(found & FND_SPEC) ? spec.Specularity : 0,
(found & FND_MTTR) ? mttr.Index : 0);
p1 = edge->Edges[face->Connects[i][0]][0];
p2 = edge->Edges[face->Connects[i][0]][1];
p3 = edge->Edges[face->Connects[i][1]][0];
p3 = ((p1 == p3) || (p2 == p3)) ?
edge->Edges[face->Connects[i][1]][1] : p3;
if ((pnts->Points[p1].X == pnts->Points[p2].X)
&& (pnts->Points[p1].Y == pnts->Points[p2].Y)
&& (pnts->Points[p1].Z == pnts->Points[p2].Z))
degen++;
else if ((pnts->Points[p1].X == pnts->Points[p3].X)
&& (pnts->Points[p1].Y == pnts->Points[p3].Y)
&& (pnts->Points[p1].Z == pnts->Points[p3].Z))
degen++;
else if ((pnts->Points[p2].X == pnts->Points[p3].X)
&& (pnts->Points[p2].Y == pnts->Points[p3].Y)
&& (pnts->Points[p2].Z == pnts->Points[p3].Z))
degen++;
else
{
fprintf(ofh, "triangle {\n");
fprintf(ofh, "\tp1\tT2AV_%d\n", p1);
fprintf(ofh, "\tp2\tT2AV_%d\n", p2);
fprintf(ofh, "\tp3\tT2AV_%d\n", p3);
fprintf(ofh, "\tpatt\t%s\n", surf->name);
fprintf(ofh, "}\n\n");
}
}
if (degen)
CHECKTERSE { fprintf(stdout, "%d of %d triangle degenerative\n", degen, face->TCount); }
CHECKTERSE { fprintf(stdout, "Axis bounds: <%f, %f, %f> - <%f, %f, %f>\n\n",
mn[0], mn[2], mn[1], mx[0], mx[2], mx[1]); }
}
if (((found & FND_PRP0) && (!(prp.Props[PRP_SMOOTH]))) || ((found & FND_PRP1) && (!(prp1.Props[PRP1_PHONG]))))
fprintf(ofh, "smoothoff\n");
}
if (found & FND_PNTS)
free(pnts);
if (found & FND_EDGE)
free(edge);
if (found & FND_FACE)
free(face);
if (found & FND_TLST)
free(tlst);
if (found & FND_RLST)
free(rlst);
if (found & FND_CLST)
free(clst);
}
void GetObjChunk(int ifd, int len)
{
Chunk chunk;
while (len) {
len -= read(ifd, &chunk, sizeof(Chunk));
if (chunk.name == MakeName("EXTR")) {
CHECKVERBOSE { fprintf(stdout, "\tEXTR: found\n"); }
lseek(ifd, chunk.len, 1);
len -= chunk.len;
}
else if (chunk.name == MakeName("TOBJ")) {
CHECKVERBOSE { fprintf(stdout, "\tTOBJ:\n\n"); }
lseek(ifd, chunk.len, 1);
len -= chunk.len;
}
else if (chunk.name == MakeName("DESC")) {
CHECKVERBOSE { fprintf(stdout, "\tDESC:\n"); }
GetDescChunk(ifd, chunk.len);
len -= chunk.len;
}
else {
CHECKTERSE { fprintf(stdout, "\t%.4s: Found unknown chunk\n", &chunk.name); }
lseek(ifd, chunk.len, 1);
len -= chunk.len;
}
}
}
void GetInfoChunk(int ifd, int len)
{
Chunk chunk;
while (len) {
len -= read(ifd, &chunk, sizeof(Chunk));
if (chunk.name == MakeName("BRSH")) {
BRSH brsh;
len -= ReadData(ifd, &brsh, sizeof(BRSH));
CHECKVERBOSE { fprintf(stdout, "\tBRSH: #%d = %s\n", brsh.Number, brsh.Filename); }
}
else if (chunk.name == MakeName("STNC")) {
STNC stnc;
len -= ReadData(ifd, &stnc, sizeof(STNC));
CHECKVERBOSE { fprintf(stdout, "\tSTNC: #%d = %s\n", stnc.Number, stnc.Filename); }
}
else if (chunk.name == MakeName("TXTR")) {
TXTR txtr;
len -= ReadData(ifd, &txtr, sizeof(TXTR));
CHECKVERBOSE { fprintf(stdout, "\tTXTR: #%d = %s\n", txtr.Number, txtr.Filename); }
}
else if (chunk.name == MakeName("OBSV")) {
OBSV obsv;
len -= ReadData(ifd, &obsv, sizeof(OBSV));
CHECKTERSE { fprintf(stdout, "\tOBSV: Location = <%f, %f, %f>\n", obsv.Camera.X/65536.0, obsv.Camera.Y/65536, obsv.Camera.Z/65536.0); }
CHECKTERSE { fprintf(stdout, "\t Rotate = <%f, %f, %f>\n", obsv.Rotate.X/65536.0, obsv.Rotate.Y/65536, obsv.Rotate.Z/65536.0); }
CHECKTERSE { fprintf(stdout, "\t Focal Len. = %f\n", obsv.Focal/65536.0); }
}
else if (chunk.name == MakeName("OTRK")) {
OTRK otrk;
len -= ReadData(ifd, &otrk, sizeof(OTRK));
CHECKVERBOSE { fprintf(stdout, "\tOTRK: %s\n", otrk.Trackname); }
}
else if (chunk.name == MakeName("OSTR")) {
CHECKVERBOSE { fprintf(stdout, "\tOSTR: found\n"); }
lseek(ifd, chunk.len, 1);
len -= chunk.len;
}
else if (chunk.name == MakeName("FADE")) {
CHECKVERBOSE { fprintf(stdout, "\tFADE: found\n"); }
lseek(ifd, chunk.len, 1);
len -= chunk.len;
}
else if (chunk.name == MakeName("SKYC")) {
CHECKVERBOSE { fprintf(stdout, "\tSKYC: found\n"); }
lseek(ifd, chunk.len, 1);
len -= chunk.len;
}
else if (chunk.name == MakeName("AMBI")) {
CHECKVERBOSE { fprintf(stdout, "\tAMBI: found\n"); }
lseek(ifd, chunk.len, 1);
len -= chunk.len;
}
else if (chunk.name == MakeName("GLB0")) {
CHECKVERBOSE { fprintf(stdout, "\tGLB0: found\n"); }
lseek(ifd, chunk.len, 1);
len -= chunk.len;
}
else {
CHECKTERSE { fprintf(stdout, "\t%.4s: Found unknown chunk\n", &chunk.name); }
lseek(ifd, chunk.len, 1);
len -= chunk.len;
}
}
}
#define PRINTUSAGE fprintf(stderr,"%s [-q|-t|-v] [-o] [-s scalefactor] infile outfile\n", argv[0]);
void parsecl(int argc, char **argv)
{
int i;
for (i=1; i<argc; i++)
{
if (argv[i][0] != '-')
{
fprintf(stderr, "%s: malformed option %s\n", argv[0], argv[i]);
PRINTUSAGE;
exit(20);
}
switch (argv[i][1])
{
case 'v':
printmode = VERBOSE;
break;
case 't':
printmode = TERSE;
break;
case 'q':
printmode = QUIET;
break;
case 'o':
flags |= FL_OBJECTS;
break;
case 's':
i++;
scalefactor = atof(argv[i]);
break;
default:
fprintf(stderr, "%s: illegal option %s\n", argv[0], argv[i]);
PRINTUSAGE;
exit(20);
}
}
}
void main(int argc, char **argv)
{
int ifd=-1;
Form form;
Chunk chunk;
int len;
if ((argc < 3) || (argc > 6)) {
PRINTUSAGE;
goto cleanup;
}
parsecl(argc-2, argv);
if ((ifd = open(argv[argc==4?2:1], O_RDONLY)) == -1) {
fprintf(stdout, "turbo2arrt: could not open input file %s\n", argv[argc==4?2:1]);
goto cleanup;
}
if (!(ofh = fopen(argv[argc==4?3:2], "w"))) {
fprintf(stdout, "turbo2arrt: could not open output file %s\n", argv[argc==4?3:2]);
goto cleanup;
}
filename = argv[argc==4?2:1];
read(ifd, &form, sizeof(Form));
if ((form.form != MakeName("FORM")) || (form.type != MakeName("TDDD"))) {
fprintf(stdout, "turbo2arrt: %s is not proper file type\n", argv[1]);
goto cleanup;
}
len = read(ifd, &chunk, sizeof(Chunk));
while (len) {
if (chunk.name == MakeName("INFO")) {
CHECKVERBOSE { fprintf(stdout, "INFO:\n"); }
GetInfoChunk(ifd, chunk.len);
CHECKVERBOSE { fprintf(stdout, "\n\n"); }
}
else if (chunk.name == MakeName("OBJ ")) {
CHECKVERBOSE { fprintf(stdout, "OBJ :\n"); }
GetObjChunk(ifd, chunk.len);
CHECKVERBOSE { fprintf(stdout, "\n"); }
}
else {
CHECKTERSE { fprintf(stdout, "%.4s: Found unknown chunk\n\n\n", &chunk.name); }
lseek(ifd, chunk.len, 1);
}
len = read(ifd, &chunk, sizeof(Chunk));
}
CHECKTERSE { fprintf(stdout, "***\n\tObject Bounds: <%f, %f, %f> - <%f, %f, %f>\n", imn[0], imn[2], imn[1], imx[0], imx[2], imx[1]); }
cleanup:
if (ifd != -1)
close(ifd);
if (ofh)
fclose(ofh);
}